<?php
include_once 'library/Entity/BaseEntity.php';
class BaseGrid{

	const FORM_SURFIX = "Grid";
	const SORT_MEMBER = 'sortmember';
	
	const COL_ORDINAL = "ordinal";
	const COL_CHECKBOX = "checkbox";
	
	const TYPE_ORDINAL = "ordinal";
	const TYPE_CHECKBOX = "checkbox";
	const TYPE_COMBOBOX = "combobox";
	const TYPE_TEXT = "text";
	const TYPE_LINK = "link";
	const TYPE_LINK_EDIT = "link_edit";
	const TYPE_LINK_DELETE = "link_delete";
	const TYPE_ACTION = "action";
	const TYPE_STATUS = "status";
	
	const ORDERBY_COL = "orderby";
	const ORDERBY_WITH = "orderwith";
	
	const TOTAL_ROWS = "totalrows";
	
	const PAGE_NUM = "page";
	const PAGE_SIZE = "size";
	const PAGE_NUM_DEFAULT = 1;
	const PAGE_SIZE_DEFAULT = 20;
	
	protected $headerLb = array(
	BaseEntity::CREATEBY => 'Tạo bởi',
	BaseEntity::CREATETIME => 'Tạo lúc',
	BaseEntity::LASTUPDATEBY => 'Cập nhật lần cuối bởi',
	BaseEntity::LASTUPDATETIME => 'Cập nhật lần cuối lúc',
	BaseEntity::ROWVERSION => 'Số lần cập nhật',
	BaseEntity::STATUS => 'Trạng thái'
	);
	
	private $_data;
	/**
	 * HttpContext.
	 * @var HttpContext
	 */
	protected $_context;
	/**
	 * Table Name.
	 * @var String
	 */
	private $_tableName;
	/**
	 * BaseEntity.
	 * @var BaseEntity
	 */
	private $_entity;
	/**
	 * BaseForm.
	 * @var BaseForm
	 */
	private $_form;
	
	private $cssClass;
	
	protected $seachEntity = array(
		
	);
	
	public $cols = array(
	
	
	);
	
	protected $searchCondition = null;
	
	public function __construct(){
		$this->init();
	}
	protected $totalResult = 0;
	protected $totalPage = 0;
	/**
	 * Construction Init Data.
	 */
	public function init(){
		
	}
	/**
	 * Before Render.
	 */
	public function _preRender(){
		
	}
	public function render(){
		$this->_preRender();
		$this->getSearchCondition();
		$this->_data = $this->searchResult();
		$this->totalResult = $this->getTotalResult();
		$this->totalPage = $this->getTotalPage();
		$this->renderTable();
	}
	
	private function renderTable(){
		$columns = $this->cols;
		$hasOrdinal = false;
		$hasCheckbox = false;
		echo '<table class="tgrid '.$this->cssClass.'">';
		echo '<thead><tr>';
		if(isset($columns[BaseGrid::COL_ORDINAL])){
			echo '<th class="ordinal">#</th>';
			unset($columns[BaseGrid::COL_ORDINAL]);
			$hasOrdinal = true;
		}
		if(isset($columns[BaseGrid::COL_CHECKBOX])){
			echo '<th class="checkbox"><input type="checkbox" name="checkall"></th>';
			unset($columns[BaseGrid::COL_CHECKBOX]);
			$hasCheckbox = true;
		}
		foreach ($columns as $key=>$value) {
			echo '<th '.BaseGrid::SORT_MEMBER.'="'.$value[0].'">'.$this->headerLb[$key].'</th>';
		}
		echo '</tr></thead>';
		echo '<tbody>';
		
		$i = 1;
		foreach ($this->_data as $value) {
			$focus = '';if($i%2 == 0)$focus = 'class="focus"';
			echo '<tr '.$focus.'>';
			if($hasOrdinal){
				echo '<td class="ordinal">'.$i.'</td>';
			}
			if($hasCheckbox){
				echo '<td class="checkbox"><input type="checkbox" name="'.$this->_tableName."_".$i.'"></td>';
			}
			foreach ($columns as $skey=>$svalue) {
				switch ($svalue[1]) {
					case BaseGrid::TYPE_TEXT:
					$this->renderText($value, $svalue);
					break;
					case BaseGrid::TYPE_LINK:
					$this->renderLink($value, $svalue);
					break;
					default:
						;
					break;
				}
			}
			echo '</tr>';
			$i++;
		}
		echo '</tbody>';
		echo '<tfoot><tr class="pagenav">';
		echo '<td colspan="'.count($this->cols).'">';
		echo '<div class="nav">';
			$this->renderPageCombo();
			$this->renderPageNumber();
		echo '</div>';	
		echo '<div class="info">';
		$this->renderPagingInfo();
		echo '</div>';
		echo '</td>';
		echo '</tr></tfoot>';
		echo '</table>';
	}
	protected function renderPagingInfo(){
		$start = (($this->searchCondition[BaseGrid::PAGE_NUM] - 1) * $this->searchCondition[BaseGrid::PAGE_SIZE]) + 1;
		$end = $start + $this->searchCondition[BaseGrid::PAGE_SIZE] - 1;
		if($end>$this->totalResult) $end = $this->totalResult;
		if($start < $end){
			echo 'Dòng thứ ' .$start;
			echo ' đến ' .$end;
			echo ' trong tổng số ' . $this->totalResult.' dòng';
		}
		else{
			echo 'Dòng thứ ' .$start;
			echo ' trong tổng số ' . $this->totalResult.' dòng';
		}
	}
	private function renderPageNumber(){
		echo '<ul class="pagenum">';
		echo '<li><a href="'.$this->getPagingLink(1).'">Đầu</a></li>';
		for ($i = 1; $i <= $this->totalPage; $i++) {
			$class = "";
			if($i == $this->searchCondition[BaseGrid::PAGE_NUM])
			$class = ' class="current"';
			echo '<li '.$class.'><a href="'.$this->getPagingLink($i).'">'.$i.'</a></li>';
		}
		echo '<li><a href="'.$this->getPagingLink($this->totalPage).'">Cuối</a></li>';
		echo '</ul>';
	}
	public function getPagingLink($page){
		$link = $this->getContext()->getBaseUrl().$this->getModule().'/'.$this->_tableName.'/list/default.html?';
		foreach ($this->seachEntity as $value) {
			$key = $this->_tableName."_".$value;
			if(isset($this->searchCondition[$key]) && $this->searchCondition[$key] != "")
				$link .= $key."=".$this->searchCondition[$key]."&";
		}
		if(isset($this->searchCondition[BaseGrid::ORDERBY_COL]) && $this->searchCondition[BaseGrid::ORDERBY_COL] != "")
			$link .= BaseGrid::ORDERBY_COL."=".$this->searchCondition[BaseGrid::ORDERBY_COL]."&";
		if(isset($this->searchCondition[BaseGrid::ORDERBY_WITH]) && $this->searchCondition[BaseGrid::ORDERBY_WITH] != "")
			$link .= BaseGrid::ORDERBY_WITH."=".$this->searchCondition[BaseGrid::ORDERBY_WITH]."&";
		$link .= BaseGrid::PAGE_NUM."=".$page."&";
		$link .= BaseGrid::PAGE_SIZE."=".$this->searchCondition[BaseGrid::PAGE_SIZE];
		return $link;
	}
	private function renderPageCombo(){
		echo '<select name="'.BaseGrid::PAGE_SIZE.'">';
			echo '<option>5</option>';
			echo '<option>10</option>';
			echo '<option>20</option>';
			echo '<option>40</option>';
			echo '<option>80</option>';
			echo '<option>150</option>';
		echo '</select>';
	}
	private function renderText($data,$svalue){
		$get = $svalue[0];
		echo '<td class="'.$get.'">'.$data[$get].'</td>';
	}
	private function renderLink($data,$svalue){
		$get = $svalue[0];
		$val = $svalue[3];
		$linkdata = array();
		foreach ($svalue[3] as $sub) {
			$linkdata[$sub] = $data[$sub];
		}
		$link = StringUltil::format($svalue[2], $linkdata);
		echo '<td><a href="'.$link.'">'.$data[$get].'</a></td>';
	}
	private function getSearchCondition(){
		foreach ($this->seachEntity as $value) {
			$key = $this->_tableName."_".$value;
			$this->searchCondition[$key] = $this->_context->request($key,"");
		}
		$this->searchCondition[BaseGrid::ORDERBY_COL] = $this->_context->request(BaseGrid::ORDERBY_COL,"");
		$this->searchCondition[BaseGrid::ORDERBY_WITH] = $this->_context->request(BaseGrid::ORDERBY_WITH,"");
		$this->searchCondition[BaseGrid::PAGE_NUM] = $this->_context->request(BaseGrid::PAGE_NUM,BaseGrid::PAGE_NUM_DEFAULT);
		$this->searchCondition[BaseGrid::PAGE_SIZE] = $this->_context->request(BaseGrid::PAGE_SIZE,BaseGrid::PAGE_SIZE_DEFAULT);
	}
	/**
	 * Search query string
	 * String.
	 */
	public function searchQuery(){
		return 'select * from ' .strtolower($this->_tableName);
	}
	/**
	 * Query string to get Total rows of result
	 * @return String
	 */
	public function totalResultQuery(){
		return 'select count(*) as '.BaseGrid::TOTAL_ROWS.' from '.strtolower($this->_tableName);
	}
	protected function getTotalResult(){
		$total = DBHelper::getInstance()->fetchRow($this->totalResultQuery());
		if(isset($total[BaseGrid::TOTAL_ROWS]))
			return $total[BaseGrid::TOTAL_ROWS];
		return 0;
	}
	protected function getTotalPage(){
		if($this->totalResult < 1)
		return 0;
		else{
			if(($this->totalResult % $this->searchCondition[BaseGrid::PAGE_SIZE]) == 0)
				return (int)($this->totalResult/$this->searchCondition[BaseGrid::PAGE_SIZE]);
			else 
				return (int)(($this->totalResult/$this->searchCondition[BaseGrid::PAGE_SIZE])+1);
		}
	}
	/**
	 * Get query result.
	 * @return array
	 */
	public function searchResult(){
		$query = $this->searchQuery() .$this->getLimitQuery();
		return DBHelper::getInstance()->fetchAll($query);
	}
	protected function getLimitQuery(){
		$page = $this->searchCondition[BaseGrid::PAGE_NUM];
		$size = $this->searchCondition[BaseGrid::PAGE_SIZE];
		return ' limit ' .(($page - 1) * $size).','.$size; 
	}
	/**
	 * Edit link when click on link item
	 * @return String
	 */
	public function getEditLink(){
		return $this->getContext()->getBaseUrl().'Administrator/'.$this->_tableName.'/edit/default.html?id={0}';
	}
	public function setData($data){
		$this->_data = $data;
	}
	/**
	 * Get Result data.
	 */
	public function getData(){
		return $this->_data;
	}
	public function setContext($context){
		$this->_context = $context;
	}
	public function getContext(){
		return $this->_context;
	}
	public function setTableName($table){
		$this->_entity = EntityFactory::instance($table);
		$this->_tableName = $table;
	}
	public function getTableName(){
		return $this->_tableName;
	}
	public function setEntity($entity){
		$this->_entity = $entity;
	}
	public function getEntity(){
		return $this->_entity;
	}
	public function getSearchEntity(){
		return $this->seachEntity;
	}
	public function setForm($form){
		$this->_form = $form;
	}
	public function getForm(){
		return $this->_form;
	}
	public function setCssClass($cssClass){
		$this->cssClass = $cssClass;
	}
	public function getCssClass(){
		return $this->cssClass;
	}
	public function getModule(){
		$class = get_class($this);
		$arr = explode("_", $class);
		if(count($arr)>0)
			return $arr[0];
		return Configuration::MODULE_DEFAULT;		
	}
}